import ajax from './ajax.js'
import appsetNav from './appsetNav.js'
import widgetSet from './widgetSet.js';
import getStorage from './getStorage.js';
import Vue from 'vue';
import ifTerminalTrue from './ifTerminalTrue.js';
import ifDevTrue from './ifDevTrue.js';
import handleStateMent from './handleStateMent.js';
import deepClone from './deepClone'
import debounce from './debounce'
import findWidget from './findWidget'
import actLog from './actLog'
import getCurrentUri from './getCurrentUri'

export let handleDataBind = (listData, bindData, myItem, widgetDataKey = 'common') => {
	bindData.forEach(item => {
		// originKey的倒数第二个是目标dom(包含名称和cid)，倒数第一个是目标字段
		var originKey = item.originKey.split('%krt_'),
			len = originKey.length,
			dom = originKey[len - 2],
			targetKey = originKey[len - 1];
		//去除目标dom的名称和cid
		var cid = dom.split('%krt%')[1],
			domType = dom.split('%krt%')[0];
		//如果比对dom名称和cid都一致，那么开始寻找目标数据的值
		if (domType === myItem.type && cid === myItem.cid) {
			//bindKey的最后一个Array后的字符表示需要绑定的字段链条
			var bindKeyChain = '';
			if (item.bindType === 'list') {
				var arr = item.bindKey.split('Array%krt_'),
					len1 = arr.length;
				bindKeyChain = arr[len1 - 1];
			} else {
				bindKeyChain = item.bindKey.split('%krt_')
			}
			var chainArr = bindKeyChain.split('%krt_'),
				targetVal;
			chainArr.forEach((item, index) => {
				if (index === 0) {
					targetVal = listData[item]
				} else {
					targetVal = targetVal[item]
				}
			})
			var keyArr = widgetDataKey.split('_'),
				widgetResult;
			keyArr.forEach((item, index) => {
				if (index === 0) {
					widgetResult = myItem[item]
				} else {
					widgetResult = widgetResult[item]
				}
			})
			widgetResult[targetKey] = targetVal
		}
	})
	return myItem
}

export let getKeyData = (key, data, findTarget, notList) => {
	var bindKeyChain = [],
		obj = data;
	if (!findTarget) {
		if (key.indexOf('Array%krt_') > -1 && key.split('Array%krt_')[0]) {
			bindKeyChain = key.split('Array%krt_')[0].split('%krt_');
		}
		if(notList){
			bindKeyChain = key.split('%krt_').slice(0,-1);
		}
	} else {
		if (key.indexOf('Array%krt_') > -1 && key.split('Array%krt_').slice(-1)[0]) {
			bindKeyChain = key.split('Array%krt_').slice(-1)[0].split('%krt_');
		} else {
			bindKeyChain = key.split('%krt_')
		}
	}
	bindKeyChain.forEach(item => {
		if (item) {
			if (obj) {
				obj = obj[item]
			}
		}
	})
	return obj
}

export let findTargetData = (res, bindData, rootType) => {
	if (rootType !== 'list') {
		return res
	}
	if (bindData.length === 0) {
		return []
	}
	// 寻找数据
	var listData = getKeyData(bindData[0].bindKey, res);
	return listData;
}

export let sendAjaxRequest = (ajaxInstance, props, source, variable, pageCid, pageConfig, notToLogin) => {
	props = props()
	return new Promise(resolve => {
		// 如果一个接口需要登录，但没有token，则直接触发未登录事件，不发请求
		if(ajaxInstance.login && !uni.getStorageSync('token')){
			uni.$emit('logout-' + pageCid, {notToLogin})
			return
		}
		var bindData = ajaxInstance.bindData;
		if (source !== 'page' && bindData.length === 0) {
			resolve({
				count: 0,
				listData: [],
				bindData: []
			})
			return;
		}
		var data = {};
		ajaxInstance.data.forEach(item => {
			if (item.fromProps || item.source === 'props') {
				data[item.key] = decodeURIComponent(props[item.val] || '');
			} else if (variable && item.source === 'variable') {
				variable.some(vari => {
					if (vari.keyName === item.val) {
						data[item.key] = vari.val;
						return true
					}
				})
			} else if (item.source === 'storage') {
				// #ifdef H5
				data[item.key] = localStorage.getItem(item.val);
				// #endif
				// #ifdef MP
				data[item.key] = uni.getStorageSync(item.val);
				// #endif
			} else if (item.source === 'widget') {
				var targetCid = item.target.split('%krt%').slice(-1)[0]
				var tragetVal = findWidgetInPage(pageConfig, targetCid, item.attr)
				data[item.key] = tragetVal
			}else{
				data[item.key] = item.val;
			}
		});
		var headers = {};
		ajaxInstance.headers.forEach(item => {
			headers[item.key] = item.val;
		});
		ajax({
				url: ajaxInstance.url,
				basePathIdx: ajaxInstance.basePathIdx,
				method: ajaxInstance.method,
				data: data,
				header: headers,
				pageCid,
				needAuth: ajaxInstance.login,
				notToLogin
			})
			.then(res => {
				if(res.code === 200){
					var listData;
					if (source !== 'page') {
						listData = findTargetData(res, bindData, bindData[0].bindType);
					} else {
						listData = res
					}
					resolve({
						count: res.count,
						listData,
						bindData
					})
				}else{
					if (source === 'page') {
						resolve({
							count: res.count,
							listData: res,
							bindData
						})
					}
				}
				// 如果是页面中的列表型元素中的ajax,则可立即执行回调
				if (source !== 'page') {
					// 网络请求的回调处理
					ajaxInstance.callBack.forEach(call=>{
						var result = handleStateMent(call.stateMent, res)
						if(result){
							uni.$emit('eventCallback-' + pageCid, call.events)
						}
					})
				}
			})
			.catch(() => {
				uni.hideLoading()
				resolve({
					count: 0,
					listData: [],
					bindData: []
				})
			});
	})
}

export let makePhoneCall = phoneNum => {
	if (!phoneNum.replace(/\s/g, '')) {
		uni.showToast({
			title: '号码为空',
			icon: 'none'
		})
		return
	}
	uni.showModal({
		title: "拨打电话",
		content: phoneNum,
		success: res => {
			if (res.confirm) {
				uni.makePhoneCall({
					phoneNumber: phoneNum
				});
			}
		}
	})
}

export let copy = deepClone

//HTML标签转义（< -> &lt;）
export let removeHTMLTag = str => {
	if (typeof str === 'number' || !isNaN(str)) {
		return str + ''
	}
	if (typeof str !== 'string') {
		return ''
	}
	str = str.replace(/<\/?[^>]*>/g, ""); //去除HTML tag
	str = str.replace(/[ | ]*\n/g, "\n"); //去除行尾空白
	str = str.replace(/\n[\s| | ]*\r/g, "\n"); //去除多余空行
	// 加入常用解析
	str = str.replace(/&nbsp;/g, ' ');
	str = str.replace(/&ensp;/g, ' ');
	str = str.replace(/&emsp;/g, '　');
	str = str.replace(/&quot;/g, "'");
	str = str.replace(/&amp;/g, '&');
	str = str.replace(/&lt;/g, '<');
	str = str.replace(/&gt;/g, '>');
	str = str.replace(/&#8226;/g, '•');
	return str;
}

// 格式化时间戳
export let formatUnixTime = (val, type)=>{
	var toDay;
	if (!val) {
		val = new Date().getTime()
	}
	let unixtime = val;
	let n = 13 - unixtime.toString().length;
	let unixTimestamp = new Date(unixtime * Math.pow(10, n));
	let Y = unixTimestamp.getFullYear();
	let M =
		unixTimestamp.getMonth() + 1 >= 10 ?
		unixTimestamp.getMonth() + 1 :
		"0" + (unixTimestamp.getMonth() + 1);
	let D =
		unixTimestamp.getDate() >= 10 ?
		unixTimestamp.getDate() :
		"0" + unixTimestamp.getDate();
	let h =
		unixTimestamp.getHours() >= 10 ?
		unixTimestamp.getHours() :
		"0" + unixTimestamp.getHours();
	let m =
		unixTimestamp.getMinutes() >= 10 ?
		unixTimestamp.getMinutes() :
		"0" + unixTimestamp.getMinutes();
	let s =
		unixTimestamp.getSeconds() >= 10 ?
		unixTimestamp.getSeconds() :
		"0" + unixTimestamp.getSeconds();
	if (!type) {
		toDay = Y + "-" + M + "-" + D + " " + h + ":" + m + ":" + s; // 2018-10-26 10:06:21
	} else if (type === 1) {
		toDay = Y + "-" + M + "-" + D + " " + h + ":" + m; // 2018-10-26 10:06
	} else if (type === 2) {
		toDay = Y + "-" + M + "-" + D; // 2018-10-26
	} else if (type === 3) {
		toDay = M + "-" + D; // 10-26
	} else if (type === 4) {
		toDay = h + ":" + m + ":" + s; // 10:06:21
	}
	return toDay;
}

const getBroastParam = (para,listItem,variable,props) =>{
	var params = {};
	para.forEach(obj => {
		if (obj.source === "static") {
			params[obj.key] = obj.val
		} else if (obj.source === 'transKey') {
			params[obj.key] = getKeyData(obj.val, listItem, 1)
		} else if (variable && obj.source === 'variable') {
			variable.some(vari => {
				if (vari.keyName === obj.val) {
					params[obj.key] = vari.val
					return true
				}
			})
		} else if (obj.source === 'storage') {
			var storageVal = '';
			// #ifdef H5
			storageVal = localStorage.getItem(obj.val);
			// #endif
			// #ifdef MP
			storageVal = uni.getStorageSync(obj.val);
			// #endif
			params[obj.key] = storageVal
		} else if (obj.source === 'props') {
			params[obj.key] = props[obj.val] || ''
		}
	})
	return params
}

export let triggerEvent = (event, listItem, props, pageConfig) => {
	var pageCid = pageConfig.cid,variable = pageConfig.variable;
	props = typeof props === 'function' ? props() : props;
	var events = event;
	events.forEach(e => {
		var ifTrueTer = ifTerminalTrue(e.terminal)
		if(!ifTrueTer){
			return
		}
		var ifTrueDev = ifDevTrue(e.development)
		if(!ifTrueDev){
			return
		}
		var result = handleStateMent(e.stateMent || [], listItem, 'event', props, variable)
		if(!result){
			return
		}
		if (e.type === 'navigator') {
			var naviFn = uni.navigateTo;
			if (e.naviType === 'switchTab') {
				naviFn = uni.switchTab
			} else if (e.naviType === 'reLaunch') {
				naviFn = uni.reLaunch
			} else if (e.naviType === 'redirectTo') {
				naviFn = uni.redirectTo
			} else if (e.naviType === 'navigateBack') {
				naviFn = uni.navigateBack
				naviFn({
					delta: e.backDelta
				})
				return
			}
			if (e.ifAppsetNav) {
				appsetNav(listItem)
				return
			}
			if(e.needLogin && !getStorage('token')){
				Vue.prototype.$afterTokenError({})
				return
			}
			var url = e.url,
				params = [];
			e.params.forEach(item => {
				if (item.ifChange || item.source === 'transKey') {
					params.push(item.key + '=' + getKeyData(item.val, listItem, 1))
				} else if (variable && item.source === 'variable') {
					variable.some(vari => {
						if (vari.keyName === item.val) {
							if(/^https?:\/\//.test(vari.val)){
								params.push(item.key + '=' + encodeURIComponent(vari.val))
							}else{
								params.push(item.key + '=' + vari.val)
							}
							return true
						}
					})
				} else if (item.source === 'storage') {
					var storageVal = '';
					// #ifdef H5
					storageVal = localStorage.getItem(item.val);
					// #endif
					// #ifdef MP
					storageVal = uni.getStorageSync(item.val);
					// #endif
					params.push(item.key + '=' + storageVal)
				} else if (item.source === 'props') {
					params.push(item.key + '=' + (props[item.val] || ''))
				} else {
					if(/^https?:\/\//.test(item.val)){
						params.push(item.key + '=' + encodeURIComponent(item.val))
					}else{
						params.push(item.key + '=' + item.val)
					}
				}
			})
			params = params.join('&');
			if (!e.ifToMp && !e.ifModulePage && e.naviType !== 'navigateBack' && e.urlFromApi) {
				url = getKeyData(e.url, listItem, 1)
			}
			if (params) {
				if (url.indexOf('?') > -1) {
					url += '&' + params;
				} else {
					url += '?' + params;
				}
			}
			if (e.ifToMp) {
				uni.navigateToMiniProgram({
					appId: e.appId,
					path: url
				});
				console.log('跳转地址:', url)
				return
			}
			if((e.ifOuterChain || !e.ifModulePage) && /^(tobedeveloped)/.test(url)){
				uni.showToast({
					title: '敬请期待',
					icon: 'none'
				})
				return
			}
			if (e.ifOuterChain) {
				if (!/^https?:\/\//.test(url)) {
					return
				}
				naviFn({
					url: '/views/common/webView?url=' + encodeURIComponent(url)
				})
				console.log('跳转地址:', url)
			} else {
				if (e.ifModulePage) {
					if (!e.pageId) {
						return
					}
					var singlePageUrl = '/views/singlePage?pageId=' + e.pageId + (params ? '&' + params : '')
					naviFn({
						url: singlePageUrl
					})
					console.log('跳转地址:', singlePageUrl)
				} else {
					if (/^https?:\/\//.test(url)) {
						naviFn({
							url: '/views/common/webView?url=' + encodeURIComponent(url)
						})
						console.log('跳转地址:', url)
					} else if (/^pageId=/.test(url)) {
						var pageIdInfo = url.split('pageId=')[1].split('?')
						var pageId = pageIdInfo[0],pageIdPara = pageIdInfo[1] || ''
						var singlePageUrl = '/views/singlePage?pageId=' + pageId + '&' + pageIdPara
						naviFn({
							url: singlePageUrl
						})
						console.log('跳转地址:', singlePageUrl)
					} else if (/^phoneCall=/.test(url)) {
						var phoneNumber = url.split('phoneCall=')[1].split('?')[0]
						makePhoneCall(phoneNumber)
					} else if(/^mini=/.test(url)) {
						var miniInfo = url.split('mini=')[1].split(',')
						var miniAppid = miniInfo[0],miniPath = miniInfo[1]
						uni.navigateToMiniProgram({
							appId: miniAppid,
							path: miniPath
						});
						console.log('跳转地址:', miniPath)
					} else {
						naviFn({
							url
						})
						console.log('跳转地址:', url)
					}
				}
			}
		} else if (e.type === 'storage') {
			var params = [];
			e.params.forEach(item => {
				if (item.source === 'transKey') {
					params.push({
						key: item.key,
						val: getKeyData(item.val, listItem, 1)
					})
				} else if (variable && item.source === 'variable') {
					variable.some(vari => {
						if (vari.keyName === item.val) {
							params.push({
								key: item.key,
								val: vari.val
							})
							return true
						}
					})
				} else if (item.source === 'storage') {
					var storageVal = '';
					// #ifdef H5
					storageVal = localStorage.getItem(item.val);
					// #endif
					// #ifdef MP
					storageVal = uni.getStorageSync(item.val);
					// #endif
					params.push({
						key: item.key,
						val: storageVal
					})
				} else if (item.source === 'props') {
					params.push({
						key: item.key,
						val: props[item.val] || ''
					})
				} else {
					params.push({
						key: item.key,
						val: item.val
					})
				}
			})
			params.forEach(item => {
				// #ifdef H5
				window.localStorage.setItem(item.key, item.val)
				// #endif
				// #ifdef MP
				uni.setStorageSync(item.key, item.val)
				// #endif
			})
		} else if (e.type === 'phoneCall') {
			var mumber = e.number;
			if (e.source === 'transKey') {
				mumber = getKeyData(e.number, listItem, 1)
			} else if (variable && e.source === 'variable') {
				variable.some(vari => {
					if (vari.keyName === e.number) {
						mumber = vari.val;
						return true
					}
				})
			} else if (e.source === 'storage') {
				// #ifdef H5
				mumber = localStorage.getItem(e.number);
				// #endif
				// #ifdef MP
				mumber = uni.getStorageSync(e.number);
				// #endif
			} else if (e.source === 'props') {
				mumber = props[item.val] || ''
			}
			makePhoneCall(mumber)
		} else if (e.type === 'sendAjax') {
			e.ajaxIds.forEach(cid => {
				var lastTwoChain = cid.split('%krt_').slice(-2),
					domChain = lastTwoChain[0].split('%krt%');
				var domType = domChain[0]
				var domCid = domChain[1]
				var ajaxCid = lastTwoChain[1].split('%krt%').slice(-1)[0]
				uni.$emit('sendAjax-' + (domType === 'page' ? ('page-' + pageCid) : (pageCid + '-' + domCid)), {
					type: e.type,
					ajaxCid,
					notToLogin: e.notToLogin
				})
			})
		} else if (e.type === 'stateChange') {
			widgetSet({ pageCid, e})
		} else if (e.type === 'sendBroadCast') {
			var params = getBroastParam(e.params,listItem,variable,props)
			if(e.name === 'tabChange'){
				var broadP = {}
				var broadE = events.filter(e=>e.type==='sendBroadCast'&&e.name !== 'tabChange')
				broadE.forEach(b=>{
					var para = getBroastParam(b.params,listItem,variable,props)
					broadP = Object.assign({},broadP,para)
				})
				uni.$emit(e.name, params, broadP)
			}else{
				uni.$emit(e.name, params)
			}
		} else if (e.type === 'popup'){
			uni.$emit('pop-' + pageCid,{
				type: 'open',
				pageId: e.pageId,
				maskClose: e.maskClose,
				// popId: e.cid
			})
		} else if (e.type === 'popupClose'){
			uni.$emit('closePop-'+pageCid,{
				// popId: e.popId,
				finish: e.finish
			})
		} else if (e.type === 'toast'){
			uni.showToast({
				title: e.text,
				icon: 'none'
			})
		} else if (e.type === 'modal'){
			uni.showModal({
				title: e.title,
				content: e.content,
				showCancel: e.showCancel,
				success: res=>{
					if(res.confirm){
						uni.$emit('eventCallback-' + pageCid, e.confirmEv)
					}
				}
			})
		} else if (e.type === 'timer'){
			if(e.timerType === 'interval'){
				var timer = setInterval(()=>{
					uni.$emit('eventCallback-' + pageCid, e.targetEv)
				},e.time*1000)
				setTimeout(()=>{
					uni.$emit('eventCallback-' + pageCid, e.closeEv)
					clearInterval(timer)
				},e.closeTime*1000)
			}else if(e.timerType === 'timeout'){
				setTimeout(()=>{
					uni.$emit('eventCallback-' + pageCid, e.targetEv)
				},e.time*1000)
			}
		} else if (e.type === 'scanCode'){
			uni.scanCode({
				onlyFromCamera: !e.allowAlbum,
				success: res=> {
					console.log('scanCode-success',res);
					if(res.path){
						if(!/^\//.test(res.path)){
							res.path = '/' + res.path
						}
						uni.navigateTo({url: res.path})
					}
					if(res.result){
						uni.$emit('eventCallback-' + pageCid, e.success)
					}else{
						uni.$emit('eventCallback-' + pageCid, e.fail)
					}
				},
				fail(err) {
					console.log('scanCode-fail',err);
					uni.$emit('eventCallback-' + pageCid, e.fail)
				}
			})
		} else if (e.type === 'loading'){
			if(e.fn === 'show'){
				uni.showLoading({
					title: e.title,
					// #ifndef MP-ALIPAY
					mask: true
					// #endif
				})
			}else if(e.fn === 'hide'){
				uni.hideLoading()
			}
		} else if (e.type === 'calendar'){
			uni.$emit('openCalendar-' + pageCid,e)
		} else if(e.type === 'buriedPoint'){
			// 如果此发送链接的埋点上也绑定了分享事件,那么要把分享配置里的分享路径取出来
			var tranUrl = '',itemType = 'click';
			if(e.itemCode === '001001' || e.itemCode === '001002'){
				var shareConfig = events.filter(e=>e.type === 'sharePage');
				if(shareConfig.length > 0){
					var shareInfo = shareConfig[0]
					if (shareInfo.ifCurrent) {
						tranUrl = getCurrentUri(shareInfo.params.map(obj=>obj.key))
					} else {
						tranUrl = '/views/singlePage?pageId=' + shareInfo.pageId
					}
				}else{
					tranUrl = getCurrentUri()
				}
				if(e.itemCode === '001001'){
					itemType = 'share'
				}
			}
			actLog({
				shareLockCycle: e.shareLockCycle,
				pageCode: pageCid,
				itemType: itemType,
				itemCode: e.itemCode,
				itemName: e.itemName,
				actCode: e.actCode,
				themeCode: e.themeCode,
				withLoc: e.withLoc
			}, props, '', tranUrl)
		} else if(e.type === "variModify"){
			variable.some(vari => {
				if (vari.keyName === e.variName) {
					var targetVal = ''
					if(e.source === "list"){
						targetVal = getKeyData(e.listField, listItem, 1)
					}else if(e.source === 'widget'){
						targetVal = findWidgetInPage(pageConfig, e.target.split('%krt%').slice(-1)[0], e.attr)
					}else if(e.source === 'static'){
						targetVal = e.val
					}
					vari.val = targetVal
					return true
				}
			})
		} else if(e.type === 'openLocation'){
			var result = {}
			e.params.forEach(item=>{
				var value = ''
				if (item.source === 'transKey') {
					value = getKeyData(item.val, listItem, 1)
				} else if (variable && item.source === 'variable') {
					variable.some(vari => {
						if (vari.keyName === item.val) {
							value = vari.val
							return true
						}
					})
				} else if (item.source === 'storage') {
					// #ifdef H5
					value = localStorage.getItem(item.val);
					// #endif
					// #ifdef MP
					value = uni.getStorageSync(item.val);
					// #endif
				} else if (item.source === 'props') {
					value = props[item.val] || ''
				} else {
					value = item.val
				}
				result[item.key] = value
			})
			uni.openLocation({
				longitude: result.lng*1,
				latitude: result.lat*1,
				name: result.title,
				address: result.address
			})
		}
	});
}
const findWidgetInPage = (pageConfig, targetCid, attr)=>{
	var tragetVal = findWidget(pageConfig.page.content, targetCid, attr)
	if(tragetVal === null){
		tragetVal = findWidget(pageConfig.page.fixed.top, targetCid, attr)
	}
	if(tragetVal === null){
		tragetVal = findWidget(pageConfig.page.fixed.bottom, targetCid, attr)
	}
	if(tragetVal === null){
		tragetVal = findWidget(pageConfig.page.fixed.left, targetCid, attr)
	}
	if(tragetVal === null){
		tragetVal = findWidget(pageConfig.page.fixed.right, targetCid, attr)
	}
	return tragetVal
}
const eventHandler = (event, listItem, props, pageConfig)=>{
	return ()=>{
		triggerEvent(event, listItem, props, pageConfig)
	}
}
export let handleEvent = (event, listItem, pageConfig, props) => {
	if (!event || event.length === 0) {
		return
	}
	let eventHandlerFn = eventHandler(event, listItem, props, pageConfig)
	debounce(eventHandlerFn,500,true)
}